package com.easy.core.dbHandle.imp;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;

import com.easy.core.dbHandle.BasicDao;
import com.easy.core.dbHandle.BasicService;
import com.easy.core.dbHandle.CommonDao;
import com.easy.core.dbHandle.PaginationSupport;

/**
 * <p>Description: </p>
 * <p>CreateDate:@2013-8-23</p>
 * @author zhangj
 */
@SuppressWarnings("unchecked")
public class BasicServiceImp<T, PK extends Serializable> implements BasicService<T, PK> {
	
	public T findById(PK id) {
		if(null != basicDao) return basicDao.findById(id);
		else return (T) commonDao.findById(getClazz(0), id);
	}

	public <K> Object findById(Class<K> clazz, PK id) {
		if(null != basicDao) return basicDao.findById(clazz, id);
		else return commonDao.findById(clazz, id);
	}

	public List<T> findAll() {
		if(null != basicDao) return basicDao.findAll();
		else return (List<T>) commonDao.findAll(getClazz(0));
	}

	public <K> List<K> findAll(Class<K> clazz) {
		if(null != basicDao) return basicDao.findAll(clazz);
		else return commonDao.findAll(clazz);
	}

	public List<T> findByCriteria(DetachedCriteria dc) {
		if(null != basicDao) return basicDao.findByCriteria(dc);
		else return commonDao.findByCriteria(dc);
	}

	public List<T> findTopByCriteria(DetachedCriteria dc, int num) {
		if(null != basicDao) return basicDao.findTopByCriteria(dc, num);
		else return commonDao.findTopByCriteria(dc, num);
	}

	public Long findCountByCriteria(final DetachedCriteria dc){
		if(null != basicDao) return basicDao.findCountByCriteria(dc);
		else return commonDao.findCountByCriteria(dc);
	}
	
	public PaginationSupport<T> findPageByCriteria(DetachedCriteria dc, int pageSize, int startIndex, List<Order> orderList) {
		if(null != basicDao) return basicDao.findPageByCriteria(dc, pageSize, startIndex, orderList);
		else return commonDao.findPageByCriteria(dc, pageSize, startIndex, orderList);
	}

	public PaginationSupport<T> findPageByCriteria(DetachedCriteria dc, int pageSize, int startIndex, Order order) {
		List<Order> orderList = new ArrayList<Order>();
		orderList.add(order);
		if(null != basicDao) return basicDao.findPageByCriteria(dc, pageSize, startIndex, orderList);
		else return commonDao.findPageByCriteria(dc, pageSize, startIndex, orderList);
	}

	public List<?> findByHQL(String hql, Object... params) {
		if(null != basicDao) return basicDao.findByHQL(hql, params);
		else return commonDao.findByHQL(hql, params);
	}

	public PK save(T object) {
		if(null != basicDao) return basicDao.save(object);
		else return (PK) commonDao.save(object);
	}

	public void update(T object) {
		if(null != basicDao) basicDao.update(object);
		else commonDao.update(object);
	}

	public void delete(T object) {
		if(null != basicDao) basicDao.delete(object);
		else commonDao.delete(object);
	}

	public void delete(PK id) {
		if(null != basicDao) basicDao.delete(findById(id));
		else commonDao.delete(findById(getClazz(0), id));
	}
	
	public Session getCurrentSession(boolean allowCreate){
		if(null != basicDao) return basicDao.getCurrentSession(allowCreate);
		else return commonDao.getCurrentSession(allowCreate);
	}
	
	public SessionFactory getSessionFactory(){
		if(null != basicDao) return basicDao.getSessionFactory();
		else return commonDao.getSessionFactory();
	}

	public BasicDao<T, PK> getBasicDao() {
		return basicDao;
	}

	public void setBasicDao(BasicDao<T, PK> basicDao) {
		this.basicDao = basicDao;
	}

	public CommonDao getCommonDao() {
		return commonDao;
	}

	public void setCommonDao(CommonDao commonDao) {
		this.commonDao = commonDao;
	}

	private BasicDao<T, PK> basicDao;
	private CommonDao commonDao;
	protected Logger log = Logger.getLogger(this.getClass());
	
	private Class<?> getClazz(int Serializable){
		return (Class<?>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[Serializable];
	}
}
